# # 1.什么是闭包
# # 定义双层嵌套函数，内层函数可以访问外层函数的变量
# # 将内存函数作为外层函数的返回，此内层函数就是闭包函数
# # 2.闭包的好处和缺点
# # 优点:不定义全局变量,也可以让函数持续访问和修改一个外部变量优点:闭包函数引用的外部变量,是外层函数的内部变量。作用域封闭难以被误操作修改
# # 缺点:额外的内存占用
# # 3.nonlocal关键字的作用
# # 在闭包函数(内部函数中)想要修改外部函数的变量值
# # 需要用nonlocal声明这个外部变量

# def account_create(initial_amount=0):
#     def atm(num,deposit=True):
#         nonlocal initial_amount
#         if deposit:
#             initial_amount+=num
#             print(f"存钱+{num}, 余额为{initial_amount}")
#         else:
#             initial_amount -= num
#             print(f"取钱-{num}, 余额为{initial_amount}")
#
#     return atm        #无（）
# atm=account_create()
# atm(100)
# atm(200)
# atm(100,deposit=False)
# ========================================================
# 1.什么是装饰器
# 装饰器就是使用创建一个闭包函数,在闭包函数内调用目标函数。
# 可以达到不改动目标函数的同时，增加额外的功能。
# 2.装饰器的写法
# def sleep():
#     import time
#     import random
#     print("睡眠中-------")
#     time.sleep(random.randint(1,5))
#
# def outer(func):
#     def inner():
#         print("我要睡觉")
#         func()
#         print("睡好了")
#     return inner
#
# # 1
# # fn=outer(sleep)    #无（）
# fn()
# # 2
# def outer2(func):
#     def inner():
#         print("我要睡觉")
#         func()
#         print("睡好了")
#     return inner
#
# @outer2
# def sleep():
#     import time
#     import random
#     print("睡眠中-------")
#     time.sleep(random.randint(1,5))
#
# sleep()
# # sleep()==fn=outer2(sleep) + fn()
# ===========================================================
# 1.什么是设计模式
# 设计模式就是一种编程套路。
# 使用特定的套路得到特定的效果
# 2.什么是单例设计模式
# 单例模式就是对一个类,只获取其唯一的类实例对象,持续复用它,
# 节省内存
# 节省创建对象的开销
# =======================================================
# 1.什么是工厂模式
# 将对象的创建由使用原生类本身创建转换到由特定的工厂方法来创建
# 2.好处
# 大批量创建对象的时候有统一的入口,易于代码维护当发生修改
# 仅修改工厂类的创建方法即可符合现实世界的模式，即由工厂来制作产品(对象)
# class Person:
#     pass
# class Worker(Person):
#     pass
# class Teacher(Person):
#     pass
# class Student(Person):
#     pass
#
# class Person_Factory:
#     def Create_Person(self,type_p):
#         if type_p=='w':
#             return Worker()
#         elif type_p=='s':
#             return Student()
#         else :
#             return Teacher()
#
# pf=Person_Factory()
# stu=pf.Create_Person('s')
# worker=pf.Create_Person('w')
# tea=pf.Create_Person('t')
#
# print(type(stu))
# print(type(worker))
# print(type(tea))
# ==================================================
# 1.什么是进程
# 程序在操作系统内运行，即成为一个运行进程
# 2.什么是线程
# 进程内部可以有多个线程,程序的运行本质上就是由进程内部的线程在实际工作的。
# 3.什么是并行执行
# 多个进程同时在运行，即不同的程序同时运行,称之为:多任务并行执行
# 一个进程内的多个线程同时在运行,称之为:多线程并行执行
# ============================================================
# 1.threading模块的使用
# thread obj=threading.Thread(target=func)创建线程对象
# thread obj.start()启动线程执行
# 2.如何传参
# sing_thread =threading.Thread(target=sing)
# dance_thread =threading.Thread(target=dance, args=("我在跳舞，哈哈哈"，)
# sing_thread.start()
# dance_thread.start()
# "”名线程运行模式""”
# sing_thread =threading.Thread(target=sing)
# dance_thread = threading.Thread(target=dance, kwargs={"msg":"我在跳舞，哈哈哈”
# sing_thread.start()
# dance_thread.start()
# ==================================================
# import time
# import threading
# def sing(msg):
#     while True:
#         print(msg)
#         time.sleep(1)
# def dance(msg):
#     while True:
#         print(msg)
#         time.sleep(1)
#
# if __name__ == '__main__':
#     sing_threading=threading.Thread(target=sing,args=("xxl_sing",))
#     dance_threading=threading.Thread(target=dance,kwargs={"msg":"xxl_dance"})
#
#     sing_threading.start()
#     dance_threading.start()
# ========================================================
# # socket 客户端开发
# import socket
# socket_server=socket.socket()
# socket_server.bind(("localhost",8888))
# socket_server.listen(1)
# # listen 接受一个整数，表示链接的个数
#
# # result:tuple=socket_server.accept()
# # conn=result[0]
# # address=result[1]
#
# conn,address=socket_server.accept()
# # accept返回二元元组，第一个是链接对象，第二个是客户端地址信息
# # accept 是堵塞方法 等待客户端的链接 如果没有链接 卡在这里
#
# print(f"接收到客户端的连接，客户端的信息是{address}")
#
# #recv接受的参数是缓冲区大小，一般给1024即可
# # recv方法的返回值是一个字节数组也就是bytes对象，不是字符申
# # 可以通过decode方法通过UTF-8编码，将字节数组转换为字符串对象
# while True:
#     # 接受客户端信息，要使用客户端和服务端的本次链接对象，而非socket_server对象
#     data:str=conn.recv(1024).decode("UTF-8")
#     print(f"客户端信息{data}")
#     msg=input("输入发送给客户端的信息")
#     if msg=='exit':
#         break
#     conn.send(msg.encode("UTF-8"))
#
# conn.close()
# socket_server.close()
# ================================================================
# 正则表达式
# 1.什么是正则表达式
# 是一种字符串验证的规则，通过特殊的字符串组合来确立规则
# 用规则去匹配字符串是否满足
# 如(^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$)可以表示为一个标准邮箱的格式
# 2.re模块的三个主要方法
# re.match,从头开始匹配，匹配第一个命中项
# re.search,全局匹配，匹配第一个命中项
# re.findall,全局匹配,匹配全部命中项
# import re
# s="python1111 itheima python itcast"
# result=re.match("python",s)
# print(result)
# s="1212python xxxlxxxl12312123python pythonpython"
# result=re.search("python",s)
# print(result)
# result=re.findall("python",s)
# print(result)
import re
# s="itheima1 @@python2 !!666 ##itccast3"
# result=re.findall('[a-zA-Z0-9]',s)
# print(result)
# r='^[1-9a-zA-Z]{6,9}$'  #{}中无空格{6, 9}  错误！！！
# s='23244as'
# print(re.findall(r,s))
# r='^[1-9][1-9]{4,10}$'
# s='12232323'
# print(re.findall(r,s))
# r=r'^[\w-]+(\.[\w-]+)*@(qq|email|123)(\.[\w-]+)+$'
# s='a.b.c.d.f@qq.com'
# print(re.match(r,s))
# 1.字符串的r标记表示,字符串内转移字符无效,作为普通字符使用
# 2.正则表达式的元字符规则
# .   匹配任意1个字符(除了\n) \.匹配点本身
# []  匹配[]中列举的字符
# \d  匹配数字。即0-9
# \D  匹配非数字
# \s  匹配空白，即空格、tab键
# \S  匹配非空白
# \w  匹配单词字符，即a-2、A-2、0-9、_
# \W  匹配非单词字符
#
# ^  匹配字符串开头
# $  匹配字符串结尾
#
# *  匹配前一个规则的字符出现0至无数次
# +  匹配前一个规则的字符出现1至无数次
# ?  匹配前一个规则的字符出现0次或1次
#
# {m}    匹配前一个规则的字符出现m次
# {m,}   匹配前一个规则的字符出现最少m次
# {m,n}  匹配前一个规则的字符出现m到n次
#
# |      匹配左右任意一个表达式
# ()     将括号中字符作为一个分组
